﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using dpatoolkit.UILayer;
using BusinessLayer;
using System.Xml;
using System.Xml.XPath;
using DesignPatternDefinitions;

namespace dpatoolkit.UILayer
{
    class DPAProjectManager : IUIProjectManager
    {
        protected List<IUIProjectUnit> projects;

        public DPAProjectManager()
        {
            this.projects = new List<IUIProjectUnit>();
        }

        #region IUIProjectManager Members

        public IUIProjectUnit GetProject(string filename)
        {
            IUIProjectUnit proj = null;
            
            foreach  ( IUIProjectUnit p in projects )
            {
                if (p.File() == filename)
                {
                    proj = p;
                    break;
                }
            }
            if (null != proj)
                return proj;

            try
            {
                switch (GetProjectType(filename))
                {
                    case ProjectType.Project:
                        proj = new ProjectUIManager();
                        proj.Open(filename);
                        break;
                    case ProjectType.DesignPatternPlugin:
                        proj = new PluginEditorForm("Design Pattern", new BusinessLayer.PluginDataStructure());
                        proj.Open(filename);
                        break;
                    default:
                        ErrorMessage.Show("Unknown File Format : " + filename);
                        return null;
                        
                }

                // add the project to the internal list.
                this.projects.Add(proj);
                // Monitor the project closing event.
                proj.ProjectClosing += new ProjectClosing(proj_ProjectClosing);
                return proj;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return proj;

           
        }

        public IUIProjectUnit GetProject(ProjectType projType)
        {
            IUIProjectUnit proj = null;
            try
            {
                switch (projType)
                {
                    case ProjectType.Project:
                        proj = new ProjectUIManager();
                        break;
                    case ProjectType.DesignPatternPlugin:
                        proj = new PluginEditorForm("Design Pattern", new BusinessLayer.PluginDataStructure());
                        break;
                }

                if (false == proj.New(ProjectComponentType.ClassDiagram))
                    return null; // Probably the user called cancel

                // add the project to the internal list.
                this.projects.Add(proj);
                // Monitor the project closing event.
                proj.ProjectClosing += new ProjectClosing(proj_ProjectClosing);
            }
            catch ( Exception e)
            {
                Console.WriteLine(e.Message);
            }

            return proj;
        }

        public IUIProjectUnit GetProject(IProject _proj)
        {
            IUIProjectUnit proj = null;
            try
            {
                proj = new ProjectUIManager();

                IDesignPatternSubject sub = new ApplicationDataSet();
                sub.SetProject(_proj);

                if (false == proj.Open(sub))
                    return null; // Probably the user called cancel

                // add the project to the internal list.
                this.projects.Add(proj);
                // Monitor the project closing event.
                proj.ProjectClosing += new ProjectClosing(proj_ProjectClosing);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            return proj;

        }

        void proj_ProjectClosing(IUIProjectUnit project)
        {
            /* the project has closed, remove it from the internal list */
            this.projects.Remove(project);
        }

        public IList<IUIProjectUnit> Projects
        {
            get 
            {
                // check : potentially unsafe, private data is being passed
                // to the external world.
                return this.projects; 
            }
        }

        /// <summary>
        /// Saves all the projects
        /// </summary>
        public void SaveAll(bool confirm)
        {
            foreach (IUIProjectUnit p in this.projects)
                p.Save(confirm);
        }

        /// <summary>
        /// close all the open projects
        /// </summary>
        public void CloseAll()
        {
            foreach (IUIProjectUnit p in this.projects)
            {
                // Remove the delegate
                p.ProjectClosing -= proj_ProjectClosing;
                p.Close();
            }
        }

        #endregion

        /// <summary>
        /// Analyse the contents of the xml file and create the appropriate
        /// project.
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static ProjectType GetProjectType(string filename)
        {
            // Load the file;
            // TODO : This approach might be costly, can we use a light weight approach like
            // Linq 
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(filename);

                if (xmlDoc.DocumentElement.Name  == SchemaNames.DesignPatternPluginTag)
                {
                    // Found a design pattern file.
                    return ProjectType.DesignPatternPlugin;
                }
                else if (xmlDoc.DocumentElement.Name == SchemaNames.ProjectTag)
                {
                    // Found a project file.
                    return ProjectType.Project;
                }
            }
            catch
            {
                // Catch any exceptions, such as invalid xml
            }
            return ProjectType.Unknown;
        }

    }
}
